﻿// See https://aka.ms/new-console-template for more information

//编写面向对象程序实现长方形、正方形、三角形等形状的类。每个形状类都能计算面积、判断形状是否合法。请尝试合理使用接口/抽象类、属性来实现。
//随机创建10个形状对象，计算这些对象的面积之和。请尝试使用简单工厂设计模式来创建对象。
using System;
using System.Collections.Generic;

// 抽象基类 Shape
abstract class Shape
{
    public abstract double Area { get; }
    public abstract override string ToString(); // 添加 ToString 方法
}

// 矩形类
class Rectangle : Shape
{
    private double length;
    private double width;

    public double Length
    {
        get { return length; }
        set
        {
            if (value > 0) length = value;
            else throw new ArgumentException("输入要为正");
        }
    }

    public double Width
    {
        get { return width; }
        set
        {
            if (value > 0) width = value;
            else throw new ArgumentException("输入要为正");
        }
    }

    public override double Area
    {
        get { return Length * Width; }
    }

    // 重写 ToString 方法，返回矩形的类型和边长信息
    public override string ToString()
    {
        return $"矩形 [长度={Length}, 宽度={Width}]";
    }
}

// 正方形类
class Square : Shape
{
    private double side;

    public double Side
    {
        set
        {
            if (value > 0) side = value;
            else throw new ArgumentException("输入要为正");
        }
    }

    public override double Area
    {
        get { return side * side; }
    }

    // 重写 ToString 方法，返回正方形的类型和边长信息
    public override string ToString()
    {
        return $"正方形 [边长={side}]";
    }
}

// 三角形类
class Triangle : Shape
{
    private double a;
    private double b;
    private double c;

    public Triangle(double v1, double v2, double v3)
    {
        a = v1;
        b = v2;
        c = v3;
        if (!IsValid())
            throw new ArgumentException("输入的边长不满足三角形的条件");
    }

    public bool IsValid()
    {
        return a > 0 && b > 0 && c > 0 && a + b > c && a + c > b && b + c > a;
    }

    public override double Area
    {
        get
        {
            double s = (a + b + c) / 2;
            return Math.Sqrt(s * (s - a) * (s - b) * (s - c));
        }
    }

    // 重写 ToString 方法，返回三角形的类型和边长信息
    public override string ToString()
    {
        return $"三角形 [边长1={a}, 边长2={b}, 边长3={c}]";
    }
}

// 形状工厂类
class ShapeFactory
{
    private static Random random = new Random();

    public static Shape CreateShape()
    {
        while (true) // 循环直到生成一个有效的形状
        {
            int shapeType = random.Next(0, 3); // 随机生成0、1、2，分别代表矩形、正方形、三角形

            try
            {
                switch (shapeType)
                {
                    case 0:
                        Rectangle rect = new Rectangle();
                        rect.Length = random.Next(1, 10);
                        rect.Width = random.Next(1, 10);
                        return rect;

                    case 1:
                        Square square = new Square();
                        square.Side = random.Next(1, 10);
                        return square;

                    case 2:
                        double a = random.Next(1, 10);
                        double b = random.Next(1, 10);
                        double c = random.Next(1, 10);
                        if (IsValidTriangle(a, b, c)) // 检查三角形是否有效
                        {
                            return new Triangle(a, b, c);
                        }
                        break;

                    default:
                        throw new InvalidOperationException("未知的形状类型");
                }
            }
            catch (ArgumentException)
            {
                // 如果生成的形状无效，继续循环
                continue;
            }
        }
    }

    // 检查三角形是否有效
    private static bool IsValidTriangle(double a, double b, double c)
    {
        return a > 0 && b > 0 && c > 0 && a + b > c && a + c > b && b + c > a;
    }
}

// 主程序
class Program
{
    static void Main(string[] args)
    {
        List<Shape> shapes = new List<Shape>();
        double totalArea = 0;

        // 创建10个随机形状对象
        for (int i = 0; i < 10; i++)
        {
            Shape shape = ShapeFactory.CreateShape();
            shapes.Add(shape);
            totalArea += shape.Area;
        }

        // 输出每个形状的详细信息
        for (int i = 0; i < shapes.Count; i++)
        {
            Console.WriteLine($"形状 {i + 1}: {shapes[i]}"); // 调用 ToString 方法
            Console.WriteLine($"面积: {shapes[i].Area}");
            Console.WriteLine();
        }

        // 输出总面积
        Console.WriteLine($"所有形状的总面积: {totalArea}");
    }
}